package main

import (
    "net/http"
    "io/ioutil"
    "encoding/json"
    "strings"
)

type ServerHandler struct {
}

type CMDResult struct {
    Name    string `json:"name"`
    Success string `json:"success"`
    Error   string `json:"error"`
}

type ResponseData struct {
    Success string          `json:"success"`
    Error   string          `json:"error"`
    Detail  []*CMDResult    `json:"detail"`
}

func sendResponse(w http.ResponseWriter, status int, ret *ResponseData) {
    w.Header().Set("Connection", "close")
    w.WriteHeader(status)
    buf, _ := json.Marshal(ret)
    w.Write([]byte(buf))
}

func (s *ServerHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    var ret ResponseData

    acl := g_config.Acl
    if acl != nil {
        addr := req.RemoteAddr
        pos := strings.Index(addr, ":")
        if pos != -1 {
            addr = addr[0:pos]
        }

        if !acl.isAllow(addr) {
            ret.Success = "0"
            ret.Error = "acl deny"
            sendResponse(w, 403, &ret)
            return
        }
    }

    if req.URL.Path != "/_config" || req.Method != "POST" {
        ret.Success = "0"
        ret.Error = "forbidden path or method"
        sendResponse(w, 403, &ret)
        return
    }

    buf, err := ioutil.ReadAll(req.Body)
    if err != nil {
        ret.Success = "0"
        ret.Error = err.Error()
        sendResponse(w, 500, &ret)
        return
    }

    fdata := make([]*FileData, 0)
    err = json.Unmarshal(buf, &fdata)
    if err != nil {
        ret.Success = "0"
        ret.Error = err.Error()
        sendResponse(w, 400, &ret)
        return
    }

    ret.Detail = make([]*CMDResult, 0)
    for _,v := range fdata {
        cmdres := &CMDResult{}
        cmdres.Name = v.Name
        cmdres.Success = "1"
        cmdres.Error = ""

        if err := dealWithFileData(v); err != nil {
            cmdres.Success = "0"
            cmdres.Error = err.Error()
        }

        ret.Detail = append(ret.Detail, cmdres)
    }

    ret.Success = "1"
    ret.Error = ""
    sendResponse(w, 200, &ret)
}

func initListen(listen string) {
    s := &http.Server {
        Addr: listen,
        Handler: &ServerHandler{},
        // ReadHeaderTimeout: 5 * time.Second,
    }

    mainlog.Fatal(s.ListenAndServe())
}